package com.cn.why.springcloudskills.FaceTest;

import java.lang.reflect.Array;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

/*
 *线程测试
 */
public class MyFaceTest {
    /*线程篇
     * 1.手动关闭一个线程*/
    public static class SelfStopThread implements Runnable {
        private volatile boolean stop = false;//定义一个线程可见布尔变量
        int a = 0;

        @Override
        public void run() {
            while (!stop) {
                synchronized ("") {
                    a++;
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                        System.out.println("线程调度错误:" + e.getMessage());
                    }
                    a--;
                    String tn = Thread.currentThread().getName();//获得线程的名字
                    System.out.println(tn + ":a = " + a);
                }
            }
        }

        //线程终止
        public void setStopFlag() {
            stop = true;
        }

        //测试
        public static void main(String[] args) {
            SelfStopThread stopThread = new SelfStopThread();
            Thread t1 = new Thread(stopThread);
            t1.start();
            for (int i = 0; i < 5; i++) {
                new Thread(stopThread).start();
            }
            stopThread.setStopFlag();
        }
    }


    /*
     *2.如何控制某个方法允许并发访问线程的大小？
     *  Semaphore两个重要的方法就是semaphore.acquire() 请求一个信号量，
     * 这时候的信号量个数-1（一旦没有可使用的信号量，也即信号量个数变为负数时，再次请求的时候就会阻塞，
     * 直到其他线程释放了信号量）semaphore.release()释放一个信号量，此时信号量个数+1
     * */
    private static class SemaphoreTest {
        //初始化赋值5个最大线程,volatile保证变量的可见性
        private static Semaphore semaphore = new Semaphore(10);

        //创建线程测试semaphore控制线程数量
        public void run() {
            for (int a = 0; a < 100; a++) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //保证一个操作为一个原子操作，保证变量的可见性
                        synchronized (semaphore) {
                            test();
                        }
                    }
                }).start();
            }
        }

        //测试类
        public static void test() {
            try {
                //调用一次信号量减少一次
                semaphore.acquire();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println("线程" + Thread.currentThread().getName() + "进来了");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程" + Thread.currentThread().getName() + "出去了");
            semaphore.release();
        }
    }

    public static void main(String[] args) {
        SemaphoreTest semap = new SemaphoreTest();
        semap.run();
    }

    /*for循环导致输出i++重复*/
    public static class ForChangeTest {
        Long times = Calendar.getInstance().getTimeInMillis();
        //模拟并发
        private static CountDownLatch latch = new CountDownLatch(100);

        public void forTest() {
            for (int i = 0; i < 100; i++) {
                final int a = i;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            latch.await();
                            System.out.println(Thread.currentThread().getName() + " "+times+a);
                        } catch (Exception ex) {

                        }finally {
                            latch.countDown();
                        }
                    }
                }).start();
            }
        }

        public static void main(String[] args) {
            ForChangeTest changeTest = new ForChangeTest();
            changeTest.forTest();
        }
    }
}
